﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JSON;
using Facebook_Graph_Toolkit.FacebookObjects;

namespace Facebook_Graph_Toolkit.GraphApi {
    /// <summary>
    /// An individual entry in a profile's feed on Facebook
    /// </summary>
    [Serializable]
    public class Post : GraphApiObject{
        internal Post(JsonObject JO) : base(JO) { }
        /// <summary>
        /// Gets information of a Facebook Post using the Post ID
        /// </summary>
        /// <param name="PostID">Post ID</param>
        /// <param name="AccessToken">Access Token</param>
        public Post(string PostID,string AccessToken) : base(Helpers.WebResponseHelper.GetJsonFromFacebookObject(PostID, AccessToken)){
        }
        /// <summary>
        /// The post ID
        /// </summary>
        public string ID { get { return (string)data["id"]; } }
        /// <summary>
        /// The profile of user/page who posted the message
        /// </summary>
        public NameIDPair Owner { get { return new NameIDPair((JsonObject)data["from"]); } }
        /// <summary>
        /// Profiles mentioned or targeted in this post
        /// </summary>
        public IList<NameIDPair> Targets {
            get {
                if (data["to"] == null) return null;
                IList<NameIDPair> to = new List<NameIDPair>();
                JsonArray dataArray = (JsonArray)((JsonObject)data["to"])["data"];
                foreach (JsonObject toJO in dataArray) {
                    to.Add(new NameIDPair(toJO));
                }
                return to;
            }
        }
        /// <summary>
        /// The message of this post
        /// </summary>
        public string Message { get { return (string)data["message"]; } }

        /// <summary>
        /// The story of this post
        /// </summary>
        public string Story { get { return (string)data["story"]; } }
        /// <summary>
        /// The URL to the picture in this post, if available
        /// </summary>
        public string PictureUrl { get { return (string)data["picture"]; } }
        /// <summary>
        /// The URL to an icon representing the type of this post
        /// </summary>
        public string IconUrl { get { return (string)data["icon"]; } }
        /// <summary>
        /// The link attached to this post
        /// </summary>
        public LinkAttachment AttachedLink {
            get {
                if (data["link"] != null) return new LinkAttachment((string)data["name"], (string)data["link"], (string)data["caption"], (string)data["description"]);
                return null;
            }
        }
        /// <summary>
        /// The type of this post
        /// </summary>
        public PostType Type {
            get {
                switch ((string)data["type"]) {
                    case "status":
                        return PostType.Status;
                    case "link":
                        return PostType.Link;
                    case "photo":
                        return PostType.Photo;
                    case "video":
                        return PostType.Video;
                    case "checkin":
                        return PostType.CheckIn;
                    default:
                        return PostType.Unknown;
                }
            }
        }
        /// <summary>
        /// The time the post was initially published
        /// </summary>
        public DateTime CreatedTime {
            get {
                return Helpers.Common.RFC3339ToDateTime((string)data["created_time"]);
            }
        }
        /// <summary>
        /// The time of the last comment on this post
        /// </summary>
        public DateTime UpdatedTime {
            get {
                return Helpers.Common.RFC3339ToDateTime((string)data["updated_time"]);
            }
        }
        /// <summary>
        /// The number of likes on this post
        /// </summary>
        public int LikesCount { get {
            if (data["likes"] == null) return 0;
            return (int)((JsonObject)data["likes"])["count"]; } }
        /// <summary>
        /// The users who like this post
        /// </summary>
        public IList<NameIDPair> LikedUsers {
            get {
                if (data["likes"] == null) return null;
                IList<NameIDPair> likes = new List<NameIDPair>();
                JsonArray dataArray = (JsonArray)((JsonObject)data["likes"])["data"];
                if (dataArray == null) return null;
                foreach (JsonObject likesJO in dataArray) {
                    likes.Add(new NameIDPair(likesJO));
                }
                return likes;
            }
        }
        /// <summary>
        /// The number of comments on this post
        /// </summary>
        public int CommentsCount { get {
            if (data["comments"] == null) return 0;
            return (int)((JsonObject)data["comments"])["count"]; } }
        /// <summary>
        /// The last 50 comments on this post
        /// </summary>
        public IList<Comment> Comments {
            get {
                if (data["comments"] == null) return null;
                JsonArray dataArray = (JsonArray)((JsonObject)data["comments"])["data"];
                if (dataArray == null) return null;
                IList<Comment> comments = new List<Comment>();
                foreach (JsonObject commentJO in dataArray) {
                    comments.Add(new Comment(commentJO));
                }
                return comments;
            }
        }
        /// <summary>
        /// The application used to create this post
        /// </summary>
        public NameIDPair Application {
            get {
                if (data["application"] == null) return null;
                return new NameIDPair((JsonObject)data["application"]);
            }
        }

        /// <summary>
        /// A list of available actions on the post (includig commenting, liking and an optional app-specified action)
        /// </summary>
        public IList<PostAction> Actions {
            get {
                if (data["actions"] == null) return null;
                IList<PostAction> actions = new List<PostAction>();
                JsonArray dataArray = (JsonArray)data["actions"];
                foreach (JsonObject actionJO in dataArray) {
                    actions.Add(new PostAction(actionJO));
                }
                return actions;
            }
        }

        /// <summary>
        /// A list of users who are tagged in this check-in
        /// </summary>
        public IList<NameIDPair> WithTags {
            get {
                if (data["with_tags"] == null) return null;
                IList<NameIDPair> tags = new List<NameIDPair>();
                JsonArray dataArray = (JsonArray)((JsonObject)data["with_tags"])["data"];
                foreach (JsonObject TagJO in dataArray) tags.Add(new NameIDPair(TagJO));
                return tags;
            }
        }
        /// <summary>
        /// The place that the user has checked in
        /// </summary>
        public Place CheckInPlace { get { return new Place((JsonObject)data["place"]); } }

        /// <summary>
        /// Gets the comments in a post
        /// </summary>
        /// <param name="PostID">PostID</param>
        /// <param name="AccessToken">AccessToken</param>
        /// <param name="Offset">Number of comments to skip before returning the first comment</param>
        /// <param name="Limit">Maximum number of comments returned</param>
        /// <returns></returns>
        public IList<Comment> GetComments(string PostID, string AccessToken, int? Offset, int? Limit) {
            return Helpers.ApiCaller.GetComments(PostID, AccessToken, Offset, Limit);
        }
    }
}
